package chat.client;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.UnknownHostException;
import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.concurrent.Executors;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import sun.misc.Cleaner;

public class ChatClientUI extends JFrame implements ActionListener
{

    JButton btnExit;

    JList userNameListBox;

    JTextField userNameTextField;

    JButton btnConnect;

    public static SocketChannel client;

    public static Map<String, ChatWindow> userChatWindow = new HashMap<String, ChatWindow>();

    public static String currentUserName;

    public static DefaultListModel listModel;

    public static boolean isLoggedIn = false;

    // Properties props;

    public static String chatServerHost = "localhost";

    public static int chatServerPort = 9999;

    public ChatClientUI() throws Exception
    {
        super(); // set title for frame
        setChatServerDetails();
        /*
         * props = new Properties(); try {
         * 
         * props.load(this.getClass().getResourceAsStream("Config.properties"));
         * 
         * } catch (IOException e) {
         * System.out.println("Failed to load config.properties");
         * e.printStackTrace(); }
         */
        connectNReveiveMsg();
        if (client.isConnected())
        {
            showChatClientUI();
        }

    }

    public void connectNReveiveMsg()
    {
        try
        {
            client = SocketChannel.open();
            client.configureBlocking(false);
            client.connect(new java.net.InetSocketAddress(chatServerHost, chatServerPort));
            if (client.isConnectionPending())
            {
                client.finishConnect();
            }
            if (client.isConnected())
            {
                new MessageReceiver();
            }
            else
            {
                JOptionPane.showMessageDialog(null,
                        "Chat server Appears to be down,Please try after some time", "Message Box",
                        JOptionPane.OK_OPTION);
            }
        }
        catch (UnknownHostException e)
        {
            System.out.println("Failed to connect to chat server:" + e);
        }
        catch (IOException e)
        {
            System.out.println("Failed to connect to chat server:" + e);
        }
    }

    public void showChatClientUI()
    {
        btnExit = new JButton("Exit");
        JLabel jlabel = new JLabel("UserName");
        userNameTextField = new JTextField(12);
        btnConnect = new JButton("Connect");
        btnConnect.addActionListener(this);
        listModel = new DefaultListModel();
        userNameListBox = new JList(listModel);
        addListener(userNameListBox);
        JScrollPane sp = new JScrollPane(userNameListBox, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        add(sp, "Center");
        JPanel bp2 = new JPanel(new FlowLayout());
        bp2.add(jlabel);
        bp2.add(userNameTextField);
        bp2.add(btnConnect);
        bp2.add(btnExit);
        add(bp2, "North");
        btnExit.addActionListener(this);
        setPreferredSize(new Dimension(375, 600));
        // setResizable(false);
        setVisible(true);
        pack();
        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        attachCloseListener();

    }

    public void handleLogin()
    {
        try
        {
            System.out.println("Logged in status:" + isLoggedIn);
            if (!isLoggedIn)
            {
                currentUserName = userNameTextField.getText();
                if (currentUserName != null && !currentUserName.trim().equals(""))
                {
                    String password = "password123";
                    String msgToServer = StringUtils.getFormattedString(
                            RequestActionCodes.LOGIN_ACTION_CODE, currentUserName)
                            + ";password="
                            + password;
                    invokeWriteOperation(msgToServer);
                    setTitle(currentUserName);
                }
            }
            else
            {
                JOptionPane.showMessageDialog(null, "Already an user associated with this window",
                        "Message Box", JOptionPane.OK_OPTION);
            }
        }
        catch (IOException e)
        {
            System.out.println("Failed to connect to chat server:" + e);
        }
    }

    public void handleLogout()
    {
        try
        {
            if (isLoggedIn)
            {
                invokeWriteOperation(StringUtils.getFormattedString(
                        RequestActionCodes.LOGOUT_ACTION_CODE, currentUserName));
            }
            System.exit(0);
        }
        catch (IOException e)
        {
            System.out.println("Failed to logout from chat server:" + e);
        }
    }

    public static void main(String... args)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });

    } // end of main

    public static void createAndShowGUI()
    {

        try
        {
            new ChatClientUI();
        }
        catch (Exception ex)
        {
            System.out.println("Un expected Error in opening chat window " + ex.getMessage());
        }

    }

    public void openChatWindow(String toUserName)
    {
        try
        {
            ChatWindow chatWindow = new ChatWindow(toUserName);
            userChatWindow.put(toUserName, chatWindow);
        }
        catch (Exception ex)
        {
        }
    }

    private void invokeWriteOperation(String msg) throws IOException
    {
        new MessageSender(msg);

    }

    // inner class for Messages Thread

    public void addListener(JList list)
    {
        list.addMouseListener(new MouseAdapter()
        {
            public void mouseClicked(MouseEvent evt)
            {
                JList list = (JList) evt.getSource();
                if (evt.getClickCount() == 2)
                {
                    try
                    {
                        openChatWindow((String) list.getSelectedValue());
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
        });
    }

    public void attachCloseListener()
    {
        addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                showConfirmExitMessageBox();
            }
        });
    }

    public void actionPerformed(ActionEvent evt)
    {

        if (evt.getSource() == btnExit)
        {
            showConfirmExitMessageBox();
        }
        else if (evt.getSource() == btnConnect)
        {
            handleLogin();
        }

    }

    public void showConfirmExitMessageBox()
    {
        int confirmed = JOptionPane.showConfirmDialog(null,
                "Are you sure you want to exit from chat application ?", "Confirm Exit",
                JOptionPane.YES_NO_OPTION);

        if (confirmed == JOptionPane.YES_OPTION)
        {
            handleLogout();
            dispose();
        }
    }

    public void setChatServerDetails()
    {
        String name = JOptionPane.showInputDialog(null,
                "Please Provide chat server details in Host:Port format", "Server Details",
                JOptionPane.PLAIN_MESSAGE);
        if (name != null && !name.trim().equals(""))
        {
            String[] hostPort = name.split(":");
            chatServerHost = hostPort[0];
            chatServerPort = Integer.parseInt(hostPort[1]);

        }
        System.out.println(chatServerHost +"    "+chatServerPort);

    }

} // end of client

